package com.handpay.nocardpay.baselibrary.db.ormlite;

import android.content.Context;

import com.handpay.nocardpay.baselibrary.logutils.HPLog;
import com.handpay.nocardpay.baselibrary.notification.model.bean.NoticeBody;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.stmt.QueryBuilder;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author sxshi on 2017/4/6.
 *         email:emotiona_xiaoshi@126.com
 *         describe:Crud operation of database
 */

public class DataBaseModel {
    private DataBaseHelper dataBaseHelper;
    private Dao<NoticeBody, Integer> noticeDao;
    private static DataBaseModel instance;

    private DataBaseModel(Context context) {
        dataBaseHelper = DataBaseHelper.getDBHelper(context);
        try {
            noticeDao = getNoticeDao();
        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Get noticeDao faile" + e);
        }
    }

    /***
     *
     * @param context
     * @return
     */
    public static synchronized DataBaseModel getInstance(Context context) {
        if (instance == null) {
            synchronized (DataBaseHelper.class) {
                if (instance == null) {
                    instance = new DataBaseModel(context);
                }
            }
        }
        return instance;
    }

    /***
     * @return 得到业务操作类
     * @throws SQLException sql异常
     */
    public Dao<NoticeBody, Integer> getNoticeDao() throws SQLException {
        if (noticeDao == null) {
            noticeDao = dataBaseHelper.getDao(NoticeBody.class);
        }
        return noticeDao;
    }

    /**
     * 添加一条消息
     *
     * @param addNotice 需要添加的消息
     */
    public void addNotice(NoticeBody addNotice) {
        if (isExistNotice(addNotice)) {
            HPLog.d(HPLog.SSX_TAG, "This message already exists, we should delete the current message before adding.");
            deleteNotice(addNotice);
        }
        try {
            noticeDao.create(addNotice);//如果消息不存在则添加
        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Add notice faile！" + e);
        }

    }

    /**
     * 数据库插入数据
     *
     * @param noticeBodies 服务器获取消息列表
     */
    public void addAllNotices(List<NoticeBody> noticeBodies) {
        try {
            noticeDao.create(noticeBodies);
        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Add notices faile！" + e);
        }
    }

    /**
     * 查询数据库是否存在该条记录
     *
     * @param noticeBody 检测的noticeBody
     * @return ture 已经存在 false 不存在
     */
    public boolean isExistNotice(NoticeBody noticeBody) {
        return noticeBody.equals(queryNotice(noticeBody));
    }

    /***
     * 检测是否含有未读信息
     * @param userId 用户编号
     * @return 返回是否有未读信息
     */
    public boolean isReadNotice(String userId) {
        List<NoticeBody> noticeBodies = new ArrayList<>();
        for (NoticeBody noticeBody : queryNotices(userId)) {
            if (!noticeBody.isRead()) {
                noticeBodies.add(noticeBody);
            }
        }
        return noticeBodies.size() > 0;
    }


    /**
     * 查询所有的通知消息
     *
     * @return 返回数据库通知消息(实现分页查询)
     */
    public List<NoticeBody> queryNotices(String userId) {
        List<NoticeBody> noticeBodies = new ArrayList<>();
        try {
            QueryBuilder<NoticeBody, Integer> queryBuilder = noticeDao.queryBuilder();
//            queryBuilder.offset(0L);//起始位置
//            queryBuilder.limit(20L);//查询20条记录
            noticeBodies = queryBuilder.orderBy("time", false).where().eq("userId", userId).query();//按照消息推送时间排序

        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Query notices  faile！" + e);
        }
        return noticeBodies;
    }

    /**
     * 查询所有的通知消息
     *
     * @return 返回数据库通知消息(实现分页查询)
     */
    public List<NoticeBody> queryNotices(String userId,long offset,long limit) {
        List<NoticeBody> noticeBodies = new ArrayList<>();
        try {
            QueryBuilder<NoticeBody, Integer> queryBuilder = noticeDao.queryBuilder();
            queryBuilder.offset(offset);//起始位置
            queryBuilder.limit(limit);//查询20条记录
            noticeBodies = queryBuilder.orderBy("time", false).where().eq("userId", userId).query();//按照消息推送时间排序

        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Query notices  faile！" + e);
        }
        return noticeBodies;
    }

    /**
     * 删除超出限制的记录
     * @param userId
     * @param limit
     */
    public void deleteNotice(String userId,long limit) {
        QueryBuilder<NoticeBody, Integer> queryBuilder = noticeDao.queryBuilder();
        try {
            long count = queryBuilder.orderBy("time", false).where().eq("userId", userId).countOf();
            long overCount = (count - limit);
            if (overCount > 0) {
                List<NoticeBody> noticeBodies = queryNotices(userId,limit,overCount);
                noticeDao.delete(noticeBodies);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询未读消息数
     *
     * @param userId
     * @return
     */
    public int queryNoReadCount(String userId) {
        List<NoticeBody> datas = queryNotices(userId);
        int count = 0;
        for (NoticeBody obj : datas) {
            if (!obj.isRead()) {
                count++;
            }
        }
        return count;
    }

    /**
     * 查询某一条消息
     *
     * @param queryNotice 需要查询的消息
     * @return 返回一条消息
     */
    public NoticeBody queryNotice(NoticeBody queryNotice) {
        NoticeBody resultNotice = new NoticeBody();
        try {
//            resultNotice = noticeDao.queryForSameId(queryNotice);//一条消息唯一性判断条件： usetId+noticeId
            resultNotice = noticeDao.queryBuilder().where().eq("userId", queryNotice.getUserId()).and().eq("noticeId", queryNotice.getNoticeId()).queryForFirst();
        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Query  notice by noticeId faile！" + e);
        }
        return resultNotice;
    }

    /**
     * 获取当前用户的最后一条消息
     *
     * @param userId 用户ID
     * @return 最后一条消息
     */
    @Deprecated
    public NoticeBody getLastNotice(String userId) {
        NoticeBody resultNotice = null;
        List<NoticeBody> noticeBodies = queryNotices(userId);
        for (NoticeBody noticeBody : noticeBodies) {
            if (noticeBody.getLastUpdateTime().equals(noticeBody.getTime())) {
                resultNotice = noticeBody;
                break;
            }
        }
        return resultNotice;
    }

    /**
     * 标志消息为已读
     *
     * @param updateNotice 消息编号
     */
    public synchronized void updateNotice(NoticeBody updateNotice) {
        try {
            noticeDao.update(updateNotice);
        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "update  notice status by noticeId faile！" + e);
        }
    }

    /***
     * 更新当前用户服务器最后的更新时间
     * @param userId 用戶ID
     * @param lastUpdateTime 最后更新时间
     */
    @Deprecated
    public void updateLastTime(String userId, String lastUpdateTime) {
        for (NoticeBody noticeBody : queryNotices(userId)) {
            noticeBody.setUserId(userId);
            noticeBody.setLastUpdateTime(lastUpdateTime);
            updateNotice(noticeBody);
        }
    }

    /**
     * 删除消息
     *
     * @param noticeBody 需要删除的Notice
     */
    public void deleteNotice(NoticeBody noticeBody) {
        try {
            noticeDao.delete(queryNotice(noticeBody));
            HPLog.d(HPLog.SSX_TAG, "delete  message");
        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Delete  notice by noticeId faile！" + e);
        }
    }

    /**
     * 批量删除消息
     */
    public void deleteAllNotice(String userId) {
        try {
            noticeDao.delete(queryNotices(userId));

        } catch (SQLException e) {
            HPLog.e(HPLog.SSX_TAG, "Delete  notices  faile！" + e);
        }
    }

    /**
     * 最后操作结束之后关闭数据库操作
     */
    public void destory() {
        dataBaseHelper.close();
        noticeDao = null;
    }
}